﻿#include "SNRecordManager.h"
#include "CDBConnector.h"
#include <QDebug>

#include <QDateTime>

#define CURRENT_DATESTR QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")

#define CHECK_NEW_CODE_TIMES            5

using namespace zl;
SNRecordManager* zl::SNRecordManager::m_instance = nullptr;


SNRecordManager* zl::SNRecordManager::getInstance()
{
	if (!m_instance)
	{
        m_instance = new SNRecordManager();
	}
	return m_instance;
}

void zl::SNRecordManager::Release()
{
    qDebug() << "[WARNING]" << "release sn record manager...";
    delete m_instance;
    m_instance = nullptr;
}

SNRecordManager::SNRecordManager()
{

}

SNRecordManager::~SNRecordManager()
{

}

void zl::SNRecordManager::GetEmptySNData(SNInfo& snInfo)
{
    qDebug() << "[INFO]" << "empty sn data";

    snInfo.account = "";
    snInfo.name = "";

    snInfo.action_time = "";
    snInfo.sn_info = "";
}

int32_t zl::SNRecordManager::SaveSNRecord(SNInfo& snInfo)
{
    qDebug() << "[INFO]" << "save sn record: " << snInfo.sn_info;

    QSqlQuery query = zl::CDBConnector::Instance()->CreateQuery();
    query.prepare("INSERT INTO T_SN (ACCOUNT, NAME, ACTION_TIME, SN_INFO, SN_TAIL, SN_TOTAL) \
        VALUES(:account, :name, :action_time, :sn_info, :sn_tail, :sn_total)");

    query.bindValue(":account", snInfo.account);
    query.bindValue(":name", snInfo.name);
    query.bindValue(":action_time", CURRENT_DATESTR);
    query.bindValue(":sn_info", snInfo.sn_info);
    query.bindValue(":sn_tail", snInfo.sn_tail);
    query.bindValue(":sn_total", snInfo.sn_total);

    int32_t ret = zl::CDBConnector::Instance()->ExecQuery(query);
    if (ret != zl::CDBConnector::EDBError_Success)
    {
        qDebug() << "[ERROR]" << "save sn record failed: " << ret;
        return EResult_Failed;
    }

    snInfo.action_time = CURRENT_DATESTR;

    qDebug() << "[INFO]" << "save sn record success";
    return EResult_Success;
}

int32_t zl::SNRecordManager::RemoveSNRecords(const QStringList& sn_list)
{
    qDebug() << "[INFO]" << "remove sn record list, sn record list size: " << sn_list.size();

    if (sn_list.isEmpty())
    {
        qDebug() << "[ERROR]" << "remove sn record list error, sn record list is empty";
        return EResult_Failed;
    }

    int list_size = sn_list.size();

    QString tail;

    for (int i = 0; i < list_size; i++)
    {
        QString data = sn_list.at(i);

        if (!data.isEmpty())
            tail += "?,";
        else
            qDebug() << "[ERROR]" << "remove sn record list error, one sn is empty";
    }

    tail.chop(1);        // 去掉多余的逗号

    QSqlQuery query = zl::CDBConnector::Instance()->CreateQuery();

    QString str = QString("DELETE FROM T_SN WHERE SN_INFO IN(%1)").arg(tail);

    query.prepare(str);

    for (int i = 0; i < list_size; i++)
    {
        QString data = sn_list.at(i);

        if (!data.isEmpty())
            query.bindValue(i, data);
    }

    int32_t ret = zl::CDBConnector::Instance()->ExecQuery(query);
    if (ret != zl::CDBConnector::EDBError_Success)
    {
        qDebug() << "[ERROR]" << "remove sn record list failed: " << ret;
        return EResult_Failed;
    }

    qDebug() << "[INFO]" << "remove sn record list success";
    return EResult_Success;
}

int32_t zl::SNRecordManager::SearchSNRecord(const QString& sn)
{
    qDebug() << "[INFO]" << "search sn record info by sn: " << sn;

    QSqlQuery query = zl::CDBConnector::Instance()->CreateQuery();
    query.prepare("SELECT * FROM T_SN WHERE SN_INFO=:sn_info");
    query.bindValue(":sn_info", sn);

    int32_t ret = zl::CDBConnector::Instance()->ExecQuery(query);
    if (ret != zl::CDBConnector::EDBError_Success || !query.next())
    {
        qDebug() << "[INFO]" << "record not found or query failed: " << ret;
        return EResult_Failed;
    }

    qDebug() << "[INFO]" << "search sn record info success";
    return EResult_Success;
}

int32_t zl::SNRecordManager::RemoveSNRecord(const QString& sn)
{
    qDebug() << "[INFO]" << "remove sn record info by sn: " << sn;

    QSqlQuery query = zl::CDBConnector::Instance()->CreateQuery();
    query.prepare("DELETE FROM T_SN WHERE SN_INFO=:sn_info");
    query.bindValue(":sn_info", sn);

    int32_t ret = zl::CDBConnector::Instance()->ExecQuery(query);
    if (ret != zl::CDBConnector::EDBError_Success)
    {
        qDebug() << "[INFO]" << "remove sn record failed: " << ret;
        return EResult_Failed;
    }

    qDebug() << "[INFO]" << "remove sn record info success";
    return EResult_Success;
}

int32_t zl::SNRecordManager::GetAllSNRecord(SNInfoVec& vec,
        const QString& begin_time,
        const QString& close_time,
        const QString account,
        const QString sn_info)
{
    qDebug() << "[INFO]" << "query sn record";
    QSqlQuery query = zl::CDBConnector::Instance()->CreateQuery();
    QString str = "SELECT * FROM T_SN WHERE ACTION_TIME>=:begin_time AND ACTION_TIME<:close_time";

    if (!account.isEmpty()) str += " AND ACCOUNT=:account";

    if (!sn_info.isEmpty()) str += " AND SN_INFO=:sn_info";

    str += " ORDER BY ACTION_TIME DESC";

    query.prepare(str);
    query.bindValue(":begin_time", begin_time);
    query.bindValue(":close_time", close_time);

    if (!account.isEmpty()) query.bindValue(":account", account);

    if (!sn_info.isEmpty()) query.bindValue(":sn_info", sn_info);

    int32_t ret = zl::CDBConnector::Instance()->ExecQuery(query);
    if (ret != zl::CDBConnector::EDBError_Success)
    {
        qDebug() << "[ERROR]" << "get all sn record, exec query failed: " << ret;
        return EResult_Failed;
    }

    while (query.next())
    {
        SNInfo sn_data;

        sn_data.account = query.value("ACCOUNT").toString();
        sn_data.name = query.value("NAME").toString();
        sn_data.action_time = query.value("ACTION_TIME").toString();
        sn_data.sn_info = query.value("SN_INFO").toString();
        sn_data.sn_tail = query.value("SN_TAIL").toString();
        sn_data.sn_total = query.value("SN_TOTAL").toString();

        vec.push_back(sn_data);
    }

    qDebug() << "[INFO]" << "get all sn records success: " << vec.size();
    return EResult_Success;
}

int32_t zl::SNRecordManager::GetComboCompleterInfo(QStringList& account_list, QStringList& sn_info_list)
{
    qDebug() << "[INFO]" << "get combo completer info";

    QSqlQuery query = zl::CDBConnector::Instance()->CreateQuery();

    QString str = "SELECT ACCOUNT, SN_INFO FROM T_SN";

    query.prepare(str);

    int32_t ret = zl::CDBConnector::Instance()->ExecQuery(query);
    if (ret != zl::CDBConnector::EDBError_Success)
    {
        qDebug() << "[INFO]" << "get combo completer info, exec query failed: " << ret;
        return EResult_Failed;
    }

    QString account_info, sn_info;

    while (query.next())
    {
        account_info = query.value("ACCOUNT").toString();
        sn_info = query.value("SN_INFO").toString();

        if (!account_list.contains(account_info) && !account_info.isEmpty()) account_list.append(account_info);

        if (!sn_info_list.contains(sn_info) && !sn_info.isEmpty()) sn_info_list.append(sn_info);
    }

    qDebug() << "[INFO]" << "get combo completer info success";
    return EResult_Success;
}
